package com.wql.download;

import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import javax.mail.internet.MimeUtility;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;

/**
 * 浏览器端文件下载工具类
 * 
 * @author wuqinglong
 * @time 2013年11月1日 下午1:31:10
 * @email hellowql@126.com
 */
public class HttpDownloadUtils {

	private static final int MAX_LENGTH = 154;

	// 私有构造函数
	private HttpDownloadUtils() {
	}

	/**
	 * 文件下载
	 * 
	 * @param displayName
	 * @param file
	 * @param request
	 * @param response
	 */
	public static void downFile(final String displayName, final File file, HttpServletRequest request,
			HttpServletResponse response) {
		if (file != null && file.isFile()) {
			try {
				downBytes(StringUtils.isBlank(displayName) ? file.getName() : displayName,
						FileUtils.readFileToByteArray(file), request, response);
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 下载内容
	 * 
	 * @param displayName
	 * @param contents
	 * @param request
	 * @param response
	 */
	public static void downBytes(final String displayName, final byte[] contents, HttpServletRequest request,
			HttpServletResponse response) {
		if (StringUtils.isBlank(displayName) || contents == null || contents.length == 0 || response == null) {
			return;
		}
		OutputStream out = null;
		setHeader(displayName, request, response);
		try {
			out = response.getOutputStream();
			out.write(contents);
			out.flush();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 设置响应头
	 * 
	 * @param displayName
	 * @param request
	 * @param response
	 */
	private static void setHeader(String displayName, HttpServletRequest request, HttpServletResponse response) {
		String ua = request.getHeader("user-agent");
		if (null == ua) {
			ua = "";
		}
		ua = ua.toLowerCase();
		if (ua.contains("chrome") || ua.contains("firefox")) {
			try {
				// ff,chrome支持中文，文件名过长ff会截取
				displayName = MimeUtility.encodeWord(displayName).replaceAll("\\?= =\\?GBK\\?[QB]\\?", "");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();

			}
		} else {
			if (ua.contains("msie") && (ua.contains("msie 7") || ua.contains("msie 6") || ua.contains("msie 5"))) {
				displayName = getSubChar(displayName);
			}
			try {
				// chrome,IE支持中文，但不支持空格
				displayName = URLEncoder.encode(displayName, "utf-8").replaceAll("\\+", "%20");
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
			}
		}
		// if (StringUtils.isNotEmpty(ua) && ua.contains("msie")) {
		// ua = ua.toLowerCase();
		// if (ua.contains("msie 7") || ua.contains("msie 6") ||
		// ua.contains("msie 5")) {
		// displayName = getSubChar(displayName);
		// }
		// try {
		// // chrome,IE支持中文，但不支持空格
		// displayName = URLEncoder.encode(displayName,
		// "utf-8").replaceAll("\\+", "%20");
		// } catch (UnsupportedEncodingException e) {
		// e.printStackTrace();
		// }
		// } else {
		// try {
		// // ff,chrome支持中文，文件名过长ff会截取
		// displayName =
		// MimeUtility.encodeWord(displayName).replaceAll("\\?= =\\?GBK\\?[QB]\\?",
		// "");
		// } catch (UnsupportedEncodingException e) {
		// e.printStackTrace();
		//
		// }
		// }
		response.setContentType("application/x-download");
		response.addHeader("Content-Disposition", "attachment;filename=" + displayName);
	}

	/**
	 * 截取字节--根据测试发现IE6，7只能显示154个被编码后的字符
	 * 
	 * @param str
	 * @return
	 */
	private static String getSubChar(final String str) {
		if (StringUtils.length(getEncodeStr(str)) < MAX_LENGTH) {
			return str;
		}
		String temp = null;
		int index = str.lastIndexOf(".");
		if (index > -1) {
			temp = str.substring(index);
		}
		int tIndex = 0, tempLength = getEncodeStr(temp).length();
		while (getEncodeStr(str.substring(0, ++tIndex)).length() + tempLength < MAX_LENGTH) {
			;
		}
		return str.substring(0, --index) + temp;
	}

	/**
	 * 获得编码后的字符串
	 * 
	 * @param str
	 * @return
	 */
	private static String getEncodeStr(final String str) {
		if (StringUtils.isEmpty(str)) {
			return str;
		}
		try {
			return URLEncoder.encode(str, "utf-8").replaceAll("\\+", "%20");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return str;
	}

}
